package com.hwadee.property.controller.charge;

import com.hwadee.property.pojo.ChargeItem;
import com.hwadee.property.service.IChargeItemService;
import com.hwadee.property.service.IUserService;
import com.hwadee.property.util.AjaxResult;
import com.hwadee.property.util.FileUtil;
import com.hwadee.property.util.JwtUtil;
import com.hwadee.property.dto.PageResult;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/api/charge-items")
@Api(tags = "缴费项目-ChargeItemController")
@CrossOrigin
public class ChargeItemController {

    @Autowired
    private IChargeItemService chargeItemService;

    @Autowired
    private IUserService userService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private FileUtil fileUtil;

    @GetMapping("/property/page")
    @ApiOperation(value = "【物业】获取分页的收费项目列表", notes = "根据页码、每页显示数量和收费项目名称查询分页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", defaultValue = "1", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "每页显示数量", defaultValue = "10", required = true, dataType = "int", paramType = "query"),
    })
    public AjaxResult getPage(
            @RequestHeader("Authorization") String token,
            @RequestParam(value = "current", defaultValue = "1", required = true) int current,
            @RequestParam(value = "size", defaultValue = "10", required = true) int size,
            @RequestParam(value = "chargeName", required = false) String chargeName,
            @RequestParam(value = "amount", required = false) Double amount) {
        // 如果token为空，返回错误
        if (token == null || token.isEmpty()) {
            return AjaxResult.fail("未授权, token 为空");
        }

        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            return getPage(token, current, size, chargeName, userService.getById(userId).getCommunityId(), amount);
        } catch (Exception e) {
            // token解析异常或其他异常，返回失败
            return AjaxResult.fail("生成小区当月缴费订单失败" + e.getMessage());
        }
    }

    /**
     * 获取分页的收费项目列表
     * @param current 当前页码
     * @param size 每页显示数量
     * @param chargeName 收费项目名称（可选）
     * @return 分页结果
     */
    @GetMapping("/page")
    @ApiOperation(value = "【管理员】获取分页的收费项目列表", notes = "根据页码、每页显示数量和收费项目名称查询分页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", defaultValue = "1", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "每页显示数量", defaultValue = "10", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "chargeName", value = "收费项目名称", required = false, dataType = "string", paramType = "query")
    })
    public AjaxResult getPage(@RequestHeader("Authorization") String token,
            @RequestParam(value = "current", defaultValue = "1") int current,
            @RequestParam(value = "size", defaultValue = "10") int size,
            @RequestParam(value = "chargeName", required = false) String chargeName,
            @RequestParam(value = "communityId", required = false) Long communityId,
            @RequestParam(value = "amount", required = false) Double amount) {
        try {
            PageResult<ChargeItem> result = chargeItemService.getPage(current, size, chargeName, communityId, amount);
            return AjaxResult.success(result);
        } catch (Exception e) {
            return AjaxResult.error("获取收费项目分页列表失败：" + e.getMessage());
        }
    }

    @PostMapping("/property")
    @ApiOperation(value = "【物业】新增收费项目", notes = "新增一个收费项目，需要提供收费项目名称和单位金额。备注和附件为可选参数。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "chargeName", value = "收费项目名称", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "amount", value = "收费项目单位金额", required = true, dataType = "double", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "attachment", value = "附件", required = false, dataType = "MultipartFile", paramType = "form")
    })
    public AjaxResult addChargeItem(
            @RequestHeader("Authorization") String token,
            @ApiParam(value = "收费项目名称", required = true) @RequestParam String chargeName,
            @ApiParam(value = "收费项目单位金额", required = true) @RequestParam Double amount,
            @ApiParam(value = "备注", required = false) @RequestParam(required = false) String remark,
            @ApiParam(value = "附件", required = false) @RequestParam(required = false) MultipartFile attachment) {
        // 如果token为空，返回错误
        if (token == null || token.isEmpty()) {
            return AjaxResult.fail("未授权, token 为空");
        }

        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            // 根据物业ID批量新增缴费订单
            Long communityId = userService.getById(userId).getCommunityId();

            // 调用新增函数，新增缴费项目
            return addChargeItem(token, communityId, chargeName, amount, remark, attachment);
        } catch (Exception e) {
            // token解析异常或其他异常，返回失败
            return AjaxResult.fail("新增收费项目失败" + e.getMessage());
        }
    }

    /**
     * 新增收费项目
     * @param communityID 小区 ID
     * @param chargeName 收费项目名称
     * @param amount 收费项目单位金额
     * @param remark 备注（可选）
     * @param attachment 附件（可选）
     * @return 新增的收费项目对象或错误信息
     */
    @PostMapping
    @ApiOperation(value = "【管理员】新增收费项目", notes = "新增一个收费项目，需要提供小区ID、收费项目名称和单位金额。备注和附件为可选参数。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "communityID", value = "小区 ID", required = true, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "chargeName", value = "收费项目名称", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "amount", value = "收费项目单位金额", required = true, dataType = "double", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "attachment", value = "附件", required = false, dataType = "MultipartFile", paramType = "form")
    })
    public AjaxResult addChargeItem(@RequestHeader("Authorization") String token,
            @ApiParam(value = "小区 ID", required = true) @RequestParam Long communityID,
            @ApiParam(value = "收费项目名称", required = true) @RequestParam String chargeName,
            @ApiParam(value = "收费项目单位金额", required = true) @RequestParam Double amount,
            @ApiParam(value = "备注", required = false) @RequestParam(required = false) String remark,
            @ApiParam(value = "附件", required = false) @RequestParam(required = false) MultipartFile attachment) {
        try {
            ChargeItem chargeItem = new ChargeItem();
            chargeItem.setCommunityId(communityID);
            chargeItem.setChargeName(chargeName);
            chargeItem.setAmount(Math.round(amount * 100.0)/100.0);
            chargeItem.setRemark(remark);
            if (attachment != null) {
                String attachmentPath = fileUtil.uploadFileAndGetPath(attachment, "charge_item");
                chargeItem.setAttachment(attachmentPath);
            }
            boolean success = chargeItemService.addChargeItem(chargeItem);
            if (success) {
                return AjaxResult.success(chargeItem);
            } else {
                return AjaxResult.error("新增收费项目失败");
            }
        } catch (Exception e) {
            return AjaxResult.error("新增收费项目失败：" + e.getMessage());
        }
    }

    @PutMapping("/property")
    @ApiOperation(value = "【物业】修改收费项目", notes = "根据 ID 修改收费项目信息，可选参数包括小区 ID、收费项目名称、金额、备注和附件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "收费项目 ID", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "chargeName", value = "收费项目名称", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "amount", value = "收费项目单位金额", required = false, dataType = "Double", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "attachment", value = "附件", required = false, dataType = "MultipartFile", paramType = "form")
    })
    public AjaxResult updateChargeItem(
            @RequestHeader("Authorization") String token,
            @ApiParam(value = "要修改的收费项目 ID", required = true) @RequestParam Long id,
            @ApiParam(value = "收费项目名称", required = false) @RequestParam(required = false) String chargeName,
            @ApiParam(value = "收费项目单位金额", required = false) @RequestParam(required = false) Double amount,
            @ApiParam(value = "备注", required = false) @RequestParam(required = false) String remark,
            @ApiParam(value = "附件", required = false) @RequestParam(required = false) MultipartFile attachment) {
        // 如果token为空，返回错误
        if (token == null || token.isEmpty()) {
            return AjaxResult.fail("未授权, token 为空");
        }

        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            // 获取物业所在小区的收费项目
            Long communityId = userService.getById(userId).getCommunityId();
            List<ChargeItem> chargeItems = chargeItemService.listByCommunityId(communityId);
            boolean flag = false;
            for (ChargeItem i : chargeItems) {
                if (Objects.equals(i.getId(), id)){
                    flag = true;
                    break;
                }
            }

            if (!flag) return AjaxResult.fail("小区中没有该收费项，无法修改");

            // 调用更新函数，更新缴费项目
            return updateChargeItem(token, id, communityId, chargeName, amount, remark, attachment);
        } catch (Exception e) {
            // token解析异常或其他异常，返回失败
            return AjaxResult.fail("新增收费项目失败" + e.getMessage());
        }
    }

    /**
     * 修改收费项目
     * @param id 收费项目 ID
     * @param communityID 小区 ID
     * @param chargeName 收费项目名称
     * @param amount 收费项目单位金额
     * @param remark 备注
     * @param attachment 附件
     * @return 修改结果
     */
    @PutMapping
    @ApiOperation(value = "【管理员】修改收费项目", notes = "根据 ID 修改收费项目信息，可选参数包括小区 ID、收费项目名称、金额、备注和附件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "收费项目 ID", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "communityID", value = "小区 ID", required = false, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "chargeName", value = "收费项目名称", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "amount", value = "收费项目单位金额", required = false, dataType = "Double", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "attachment", value = "附件", required = false, dataType = "MultipartFile", paramType = "form")
    })
    public AjaxResult updateChargeItem(@RequestHeader("Authorization") String token,
            @ApiParam(value = "要修改的收费项目 ID", required = true) @RequestParam Long id,
            @ApiParam(value = "小区 ID", required = false) @RequestParam(required = false) Long communityID,
            @ApiParam(value = "收费项目名称", required = false) @RequestParam(required = false) String chargeName,
            @ApiParam(value = "收费项目单位金额", required = false) @RequestParam(required = false) Double amount,
            @ApiParam(value = "备注", required = false) @RequestParam(required = false) String remark,
            @ApiParam(value = "附件", required = false) @RequestParam(required = false) MultipartFile attachment) {
        try {
            ChargeItem chargeItem = new ChargeItem();
            chargeItem.setId(id);
            if (communityID != null) chargeItem.setCommunityId(communityID);
            if (chargeName != null) chargeItem.setChargeName(chargeName);
            if (amount != null) chargeItem.setAmount(Math.round(amount * 100.0)/100.0);
            if (remark != null) chargeItem.setRemark(remark);
            if (attachment != null) {
                String attachmentPath = fileUtil.checkIfExist(chargeItem.getAttachment(), "notice");
                if (attachmentPath != null) {
                    fileUtil.deleteOldFile(attachmentPath, "charge_item");
                }
                attachmentPath = fileUtil.uploadFileAndGetPath(attachment, "charge_item");
                chargeItem.setAttachment(attachmentPath);
            }
            boolean success = chargeItemService.updateChargeItem(chargeItem);
            if (success) {
                return AjaxResult.success(chargeItem);
            } else {
                return AjaxResult.error("修改收费项目失败");
            }
        } catch (Exception e) {
            return AjaxResult.error("修改收费项目失败：" + e.getMessage());
        }
    }

    /**
     * 删除收费项目
     *
     * @param id 收费项目 ID
     * @return 删除结果
     */
    @DeleteMapping("/property")
    @ApiOperation(value = "【物业】删除收费项目", notes = "根据 ID 删除收费项目")
    @ApiImplicitParam(name = "id", value = "收费项目 ID", required = true, dataType = "Long", paramType = "path")
    public AjaxResult deleteChargeItemProperty(@RequestHeader("Authorization") String token, @RequestParam Long id) {
        try {
            // 从token中解析出用户ID
            Long userId = jwtUtil.getUserId(token);

            List<ChargeItem> chargeItems = chargeItemService
                    .listByCommunityId(userService.getById(userId).getCommunityId());
            boolean flag = false;
            for (ChargeItem i : chargeItems){
                if (i.getId().equals(id)) {
                    flag = true;
                    break;
                }
            }

            if (flag){
                return deleteChargeItem(token, id);
            }else {
                return AjaxResult.fail("所在小区中没有该收费项");
            }
        } catch (Exception e) {
            return AjaxResult.error("删除收费项目失败：" + e.getMessage());
        }
    }

    /**
     * 删除收费项目
     *
     * @param id 收费项目 ID
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    @ApiOperation(value = "【管理员】删除收费项目", notes = "根据 ID 删除收费项目")
    @ApiImplicitParam(name = "id", value = "收费项目 ID", required = true, dataType = "Long", paramType = "path")
    public AjaxResult deleteChargeItem(@RequestHeader("Authorization") String token, @PathVariable Long id) {
        try {
            String attachment = chargeItemService.getById(id).getAttachment();
            if (attachment != null) {
                String attachmentPath = fileUtil.checkIfExist(attachment, "charge_item");
                if (attachmentPath != null) {
                    fileUtil.deleteOldFile(attachmentPath, "charge_item");
                }
            }
            boolean success = chargeItemService.deleteChargeItem(id);
            if (success) {
                return AjaxResult.success("删除收费项目成功");
            } else {
                return AjaxResult.error("删除收费项目失败：未找到指定的收费项目");
            }
        } catch (Exception e) {
            return AjaxResult.error("删除收费项目失败：" + e.getMessage());
        }
    }
}
